﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using SpellCaster3.Core;
using Expand;
using Expand.Linq;
using SpellCaster3.Forms.Controls;
using System.IO;
using System.Xml.Serialization;

namespace SpellCaster3.Forms
{
    public partial class GumpPicker : Form, IInputOutput
    {
        public static RangeCollection BaseRange;
            /*= new List<IEnumerable<int>> {
            ExEnumerable.RangeBetween(1236,1246),
            ExEnumerable.Range(1260),
            ExEnumerable.RangeBetween(1263,1287),
            ExEnumerable.RangeBetween(1300,1309),
            ExEnumerable.RangeBetween(1311,1312),
            ExEnumerable.RangeBetween(1401,1415),
            ExEnumerable.Range(1782),
            ExEnumerable.RangeBetween(1789,1795),
            ExEnumerable.RangeBetween(2240,2303),
            ExEnumerable.RangeBetween(2406,2408),
            ExEnumerable.RangeBetween(2410,2419),
            ExEnumerable.RangeBetween(20480,20496),
            ExEnumerable.RangeBetween(20736,20745),
            ExEnumerable.RangeBetween(20992,21020),
            ExEnumerable.Range(21248),
            ExEnumerable.RangeBetween(21251,21257),
            ExEnumerable.RangeBetween(21280,21287),
            ExEnumerable.RangeBetween(21504,21507),
            ExEnumerable.RangeBetween(21536,21542),
            ExEnumerable.Range(21632),
            ExEnumerable.RangeBetween(23000,23015),
        };*/

        public const int IconsRowLength = 5;
        public const int IconsColLength = 2;
        public const int IconsPerPage = IconsRowLength * IconsColLength;

        public GumpPicker(RangeCollection gumpRange, int index) : this(gumpRange) { Value = index; }

        public GumpPicker() : this(BaseRange) { }

        public GumpPicker(int index) : this(BaseRange, index) { }

        public GumpPicker(RangeCollection gumpRange)
        {
            InitializeComponent();

            GumpRange = gumpRange;
            _GumpControls = new List<GumpControl>(IconsPerPage);
            for (int i = 0; i < IconsPerPage; ++i)
            {
                GumpControl current = new GumpControl();
                _GumpControls.Add(current);
                current.Click += new EventHandler(GumpControl_Click);
            }

            vScrollBar.Minimum = 0;
            vScrollBar.Maximum = (int)Math.Ceiling((decimal)(GumpRange.Range.Count / IconsPerPage));
            gumpSearch.Minimum = 0;
            gumpSearch.Maximum = GumpRange.Maximum;

            for (int x = 0; x < IconsRowLength; ++x)
                for (int y = 0; y < IconsColLength; ++y)
                    _GumpControls[x + (IconsRowLength * y)].Location = new Point(x * 44, y * 64);

            RenderGumps();

            gumpPanel.Controls.AddRange(_GumpControls.ToArray());

            DialogResult = DialogResult.Cancel;
        }

        private void GumpControl_Click(object sender, EventArgs e)
        {
            GumpControl current = sender as GumpControl;
            DialogResult = DialogResult.OK;
            Value = current.GumpIndex;
            Close();
        }

        private List<GumpControl> _GumpControls;

        public RangeCollection GumpRange { get; private set; }

        private void RenderGumps()
        {
            for (int i = vScrollBar.Value * IconsPerPage; i < (IconsPerPage * (vScrollBar.Value + 1)); ++i)
                if (i >= GumpRange.Range.Count)
                    _GumpControls[i - vScrollBar.Value * IconsPerPage].GumpIndex = (-1);
                else
                    _GumpControls[i - vScrollBar.Value * IconsPerPage].GumpIndex = GumpRange.Range[i];
        }

        private void cancelButton_Click(object sender, EventArgs e)
        {
            Close();
        }

        private void searchButton_Click(object sender, EventArgs e)
        {
            vScrollBar.Value = GetIconPage((int)gumpSearch.Value);
        }

        private int GetIconPage(int iconIndex)
        {
            int tmp;
            tmp = Math.Abs(GumpRange.Range.BinarySearch(iconIndex));

            if (tmp < 0) tmp = 0;
            else if (tmp >= GumpRange.Range.Count) tmp = GumpRange.Range.Count - 1;

            tmp = (int)Math.Ceiling((decimal)(tmp / IconsPerPage));

            return tmp;
        }

        private void gumpSearch_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == (char)Keys.Enter)
            {
                e.Handled = true;
                searchButton.PerformClick();
            }
        }

        private int? _LastValue;

        private int _Value;
        public int Value
        {
            get { return _Value; }
            set
            {
                _LastValue = _Value;
                _Value = value;
                OnValueChanged(new LastValueEventArgs<int?>(_LastValue));
                OnIOValueChanged(new LastValueEventArgs<object>(_LastValue));
                vScrollBar.Value = GetIconPage(_Value);
            }
        }

        protected void OnValueChanged(LastValueEventArgs<int?> e)
        {
            if (ValueChanged != null) ValueChanged(this, e);
        }

        protected void OnIOValueChanged(LastValueEventArgs<object> lastValue)
        {
            if (IOValueChanged != null) IOValueChanged(this, lastValue);
        }

        public event EventHandler<LastValueEventArgs<int?>> ValueChanged;

        public object IOValue
        {
            get { return Value; }
            set
            {
                Value = (int)value;
            }
        }

        public event EventHandler<LastValueEventArgs<object>> IOValueChanged;

        private void vScrollBar_ValueChanged(object sender, EventArgs e)
        {
            RenderGumps();
        }
    }
}
